/**
 * echarts图表类：雷达图
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Neil (杨骥, 511415343@qq.com)
 */


var ChartBase = require('./base');
// 图形依赖
var PolygonShape = require('zrender/shape/Polygon');
// 组件依赖
require('../component/polar');
var ecConfig = require('../config');
// 雷达图默认参数
ecConfig.radar = {
    zlevel: 0,
    // 一级层叠
    z: 2,
    // 二级层叠
    clickable: true,
    legendHoverLink: true,
    polarIndex: 0,
    itemStyle: {
        normal: {
            // color: 各异,
            label: { show: false },
            lineStyle: {
                width: 2,
                type: 'solid'
            }
        },
        emphasis: {
            // color: 各异,
            label: { show: false }
        }
    },
    // symbol: null,            // 拐点图形类型
    symbolSize: 2    // 可计算特性参数，空数据拖拽提示图形大小
         // symbolRotate: null,      // 图形旋转控制
};
var ecData = require('../util/ecData');
var zrUtil = require('zrender/tool/util');
var zrColor = require('zrender/tool/color');
/**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} series 数据
     * @param {Object} component 组件
     * @constructor
     * @exports Radar
     */
function Radar(ecTheme, messageCenter, zr, option, myChart) {
    // 图表基类
    ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
    this.refresh(option);
}
Radar.prototype = {
    type: ecConfig.CHART_TYPE_RADAR,
    /**
         * 绘制图形
         */
    _buildShape: function () {
        this.selectedMap = {};
        this._symbol = this.option.symbolList;
        this._queryTarget;
        this._dropBoxList = [];
        this._radarDataCounter = 0;
        var series = this.series;
        var legend = this.component.legend;
        var serieName;
        for (var i = 0, l = series.length; i < l; i++) {
            if (series[i].type === ecConfig.CHART_TYPE_RADAR) {
                this.serie = this.reformOption(series[i]);
                this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
                serieName = this.serie.name || '';
                // 系列图例开关
                this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;
                if (this.selectedMap[serieName]) {
                    this._queryTarget = [
                        this.serie,
                        this.option
                    ];
                    // 添加可拖拽提示框，多系列共用一个极坐标，第一个优先
                    if (this.deepQuery(this._queryTarget, 'calculable')) {
                        this._addDropBox(i);
                    }
                    this._buildSingleRadar(i);
                    this.buildMark(i);
                }
            }
        }
        this.addShapeList();
    },
    /**
         * 构建数据图形
         * @param {number} 序列的index
         */
    _buildSingleRadar: function (index) {
        var legend = this.component.legend;
        var iconShape;
        var data = this.serie.data;
        var defaultColor;
        var name;
        var pointList;
        var calculable = this.deepQuery(this._queryTarget, 'calculable');
        for (var i = 0; i < data.length; i++) {
            name = data[i].name || '';
            // 图例开关
            this.selectedMap[name] = legend ? legend.isSelected(name) : true;
            if (!this.selectedMap[name]) {
                continue;
            }
            // 默认颜色策略
            if (legend) {
                // 有图例则从图例中获取颜色定义
                defaultColor = legend.getColor(name);
                iconShape = legend.getItemShape(name);
                if (iconShape) {
                    // 回调legend，换一个更形象的icon
                    iconShape.style.brushType = this.deepQuery([
                        data[i],
                        this.serie
                    ], 'itemStyle.normal.areaStyle') ? 'both' : 'stroke';
                    legend.setItemShape(name, iconShape);
                }
            } else {
                // 全局颜色定义
                defaultColor = this.zr.getColor(i);
            }
            pointList = this._getPointList(this.serie.polarIndex, data[i]);
            // 添加拐点形状
            this._addSymbol(pointList, defaultColor, i, index, this.serie.polarIndex);
            // 添加数据形状
            this._addDataShape(pointList, defaultColor, data[i], index, i, calculable);
            this._radarDataCounter++;
        }
    },
    /**
         * 获取数据的点集
         * @param {number} polarIndex
         * @param {Array<Object>} 处理的数据
         * @return {Array<Array<number>>} 点集
         */
    _getPointList: function (polarIndex, dataArr) {
        var pointList = [];
        var vector;
        var polar = this.component.polar;
        var value;
        for (var i = 0, l = dataArr.value.length; i < l; i++) {
            value = this.getDataFromOption(dataArr.value[i]);
            vector = value != '-' ? polar.getVector(polarIndex, i, value) : false;
            if (vector) {
                pointList.push(vector);
            }
        }
        return pointList;
    },
    /**
         * 添加拐点
         * @param {Array<Array<number>>} pointList 点集
         * @param {string} defaultColor 默认填充颜色
         * @param {object} data 数据
         * @param {number} serieIndex
         */
    _addSymbol: function (pointList, defaultColor, dataIndex, seriesIndex, polarIndex) {
        var series = this.series;
        var itemShape;
        var polar = this.component.polar;
        for (var i = 0, l = pointList.length; i < l; i++) {
            itemShape = this.getSymbolShape(this.deepMerge([
                series[seriesIndex].data[dataIndex],
                series[seriesIndex]
            ]), seriesIndex, series[seriesIndex].data[dataIndex].value[i], i, polar.getIndicatorText(polarIndex, i), pointList[i][0], // x
            pointList[i][1], // y
            this._symbol[this._radarDataCounter % this._symbol.length], defaultColor, '#fff', 'vertical');
            itemShape.zlevel = this.getZlevelBase();
            itemShape.z = this.getZBase() + 1;
            ecData.set(itemShape, 'data', series[seriesIndex].data[dataIndex]);
            ecData.set(itemShape, 'value', series[seriesIndex].data[dataIndex].value);
            ecData.set(itemShape, 'dataIndex', dataIndex);
            ecData.set(itemShape, 'special', i);
            this.shapeList.push(itemShape);
        }
    },
    /**
         * 添加数据图形
         * @param {Array<Array<number>>} pointList 点集
         * @param {string} defaultColor 默认填充颜色
         * @param {object} data 数据
         * @param {number} serieIndex
         * @param {number} dataIndex
         * @param {boolean} calcalable
         */
    _addDataShape: function (pointList, defaultColor, data, seriesIndex, dataIndex, calculable) {
        var series = this.series;
        // 多级控制
        var queryTarget = [
            data,
            this.serie
        ];
        var nColor = this.getItemStyleColor(this.deepQuery(queryTarget, 'itemStyle.normal.color'), seriesIndex, dataIndex, data);
        var nLineWidth = this.deepQuery(queryTarget, 'itemStyle.normal.lineStyle.width');
        var nLineType = this.deepQuery(queryTarget, 'itemStyle.normal.lineStyle.type');
        var nAreaColor = this.deepQuery(queryTarget, 'itemStyle.normal.areaStyle.color');
        var nIsAreaFill = this.deepQuery(queryTarget, 'itemStyle.normal.areaStyle');
        var shape = {
            zlevel: this.getZlevelBase(),
            z: this.getZBase(),
            style: {
                pointList: pointList,
                brushType: nIsAreaFill ? 'both' : 'stroke',
                color: nAreaColor || nColor || (typeof defaultColor === 'string' ? zrColor.alpha(defaultColor, 0.5) : defaultColor),
                strokeColor: nColor || defaultColor,
                lineWidth: nLineWidth,
                lineType: nLineType
            },
            highlightStyle: {
                brushType: this.deepQuery(queryTarget, 'itemStyle.emphasis.areaStyle') || nIsAreaFill ? 'both' : 'stroke',
                color: this.deepQuery(queryTarget, 'itemStyle.emphasis.areaStyle.color') || nAreaColor || nColor || (typeof defaultColor === 'string' ? zrColor.alpha(defaultColor, 0.5) : defaultColor),
                strokeColor: this.getItemStyleColor(this.deepQuery(queryTarget, 'itemStyle.emphasis.color'), seriesIndex, dataIndex, data) || nColor || defaultColor,
                lineWidth: this.deepQuery(queryTarget, 'itemStyle.emphasis.lineStyle.width') || nLineWidth,
                lineType: this.deepQuery(queryTarget, 'itemStyle.emphasis.lineStyle.type') || nLineType
            }
        };
        ecData.pack(shape, series[seriesIndex], // 系列
        seriesIndex, // 系列索引
        data, // 数据
        dataIndex, // 数据索引
        data.name, // 数据名称
        // 附加指标信息 
        this.component.polar.getIndicator(series[seriesIndex].polarIndex));
        if (calculable) {
            shape.draggable = true;
            this.setCalculable(shape);
        }
        shape = new PolygonShape(shape);
        this.shapeList.push(shape);
    },
    /**
         * 增加外围接受框
         * @param {number} serie的序列
         */
    _addDropBox: function (index) {
        var series = this.series;
        var polarIndex = this.deepQuery(this._queryTarget, 'polarIndex');
        if (!this._dropBoxList[polarIndex]) {
            var shape = this.component.polar.getDropBox(polarIndex);
            shape.zlevel = this.getZlevelBase();
            shape.z = this.getZBase();
            this.setCalculable(shape);
            ecData.pack(shape, series, index, undefined, -1);
            this.shapeList.push(shape);
            this._dropBoxList[polarIndex] = true;
        }
    },
    /**
         * 数据项被拖拽出去，重载基类方法
         */
    ondragend: function (param, status) {
        var series = this.series;
        if (!this.isDragend || !param.target) {
            // 没有在当前实例上发生拖拽行为则直接返回
            return;
        }
        // 被拖拽图形元素
        var target = param.target;
        var seriesIndex = ecData.get(target, 'seriesIndex');
        var dataIndex = ecData.get(target, 'dataIndex');
        // 被拖拽的图形是饼图sector，删除被拖拽走的数据
        this.component.legend && this.component.legend.del(series[seriesIndex].data[dataIndex].name);
        series[seriesIndex].data.splice(dataIndex, 1);
        // 别status = {}赋值啊！！
        status.dragOut = true;
        status.needRefresh = true;
        // 处理完拖拽事件后复位
        this.isDragend = false;
        return;
    },
    /**
         * 数据项被拖拽进来， 重载基类方法
         */
    ondrop: function (param, status) {
        var series = this.series;
        if (!this.isDrop || !param.target) {
            // 没有在当前实例上发生拖拽行为则直接返回
            return;
        }
        var target = param.target;
        // 拖拽安放目标
        var dragged = param.dragged;
        // 当前被拖拽的图形对象
        var seriesIndex = ecData.get(target, 'seriesIndex');
        var dataIndex = ecData.get(target, 'dataIndex');
        var data;
        var legend = this.component.legend;
        var value;
        if (dataIndex === -1) {
            data = {
                value: ecData.get(dragged, 'value'),
                name: ecData.get(dragged, 'name')
            };
            series[seriesIndex].data.push(data);
            legend && legend.add(data.name, dragged.style.color || dragged.style.strokeColor);
        } else {
            // 数据被拖拽到某个数据项上，数据修改
            var accMath = require('../util/accMath');
            data = series[seriesIndex].data[dataIndex];
            legend && legend.del(data.name);
            data.name += this.option.nameConnector + ecData.get(dragged, 'name');
            value = ecData.get(dragged, 'value');
            for (var i = 0; i < value.length; i++) {
                data.value[i] = accMath.accAdd(data.value[i], value[i]);
            }
            legend && legend.add(data.name, dragged.style.color || dragged.style.strokeColor);
        }
        // 别status = {}赋值啊！！
        status.dragIn = status.dragIn || true;
        // 处理完拖拽事件后复位
        this.isDrop = false;
        return;
    },
    /**
         * 刷新
         */
    refresh: function (newOption) {
        if (newOption) {
            this.option = newOption;
            this.series = newOption.series;
        }
        this.backupShapeList();
        this._buildShape();
    }
};
zrUtil.inherits(Radar, ChartBase);
// 图表注册
require('../chart').define('radar', Radar);
module.exports = Radar || module.exports;;